package ${projectDomain}.adapter.system;

import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import ${projectDomain}.adapter.BaseAdapter;
import ${projectDomain}.enums.system.api.ApiParamTypeEnum;
import ${projectDomain}.mapper.system.api.interfaces.SystemApiInterfacesExtendMapper;
import ${projectDomain}.mapper.system.api.interfaces.SystemApiInterfacesMapper;
import ${projectDomain}.pojo.dao.system.api.interfaces.SystemApiInterfacesDataDo;
import ${projectDomain}.pojo.dao.system.api.interfaces.SystemApiInterfacesInsertBatchItemDo;
import ${projectDomain}.pojo.dao.system.api.interfaces.SystemApiInterfacesSearchDo;
import ${projectDomain}.pojo.dao.system.api.interfaces.SystemApiInterfacesSingleDo;
import ${projectDomain}.pojo.dao.system.api.interfaces.SystemApiInterfacesUpdateDo;
import ${projectDomain}.pojo.vo.system.api.interfaces.SystemApiInterfacesViewVo;
import ${projectDomain}.pojo.vo.system.api.param.SystemApiParamTreeVo;
import ${projectDomain}.pojo.vo.system.api.param.SystemApiParamViewVo;
import com.unswift.utils.EncryptionUtils;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.FileUtils;
import com.unswift.utils.ObjectUtils;

@Component
@Api(value="接口api公共服务-此bean可以被任何Service引用", author="unswift", date="2023-09-05", version="1.0.0")
public class SystemApiInterfacesAdapter extends BaseAdapter{
	
	@Autowired
	@ApiField("接口api数据库操作对象")
	private SystemApiInterfacesMapper systemApiInterfacesMapper;
	
	@Autowired
	@ApiField("接口api数据库扩展操作对象")
	private SystemApiInterfacesExtendMapper systemApiInterfacesExtendMapper;
	
	@ApiField("微服务名称")
	@Value("${r'${spring.application.name}'}")
	private String serverName;
	
	@Value("${r'${unswift.token.key-name}'}")
	@ApiField("spring启动文件配置的token名称，此名称将会从request的header里面传递到后端")
	private String tokenName;
	
	@ApiMethod(value="获取接口api数据库操作对象", returns=@ApiField("数据库操作对象"))
	public SystemApiInterfacesMapper getMapper(){
		return systemApiInterfacesMapper;
	}
	
	@ApiMethod(value="获取接口api模块名称", returns=@ApiField("模块名称"))
	public String getModule(){
		return "systemApiInterfaces";
	}
	
	@ApiMethod(value="根据主键查询单个对象", params=@ApiField("主键"), returns=@ApiField("主键匹配的对象"))
	public SystemApiInterfacesDataDo findById(Long id){
		return this.findSingle(new SystemApiInterfacesSingleDo(id, null));
	}
	
	@ApiMethod(value="根据主键列表查询列表对象", params=@ApiField("主键列表"), returns=@ApiField("主键列表匹配的列表对象"))
	public List<SystemApiInterfacesDataDo> findByIds(List<Long> idList){
		return this.findList(new SystemApiInterfacesSearchDo(idList));
	}
	
	@ApiMethod(value="根据查询对象查询首个对象", params={@ApiField("查询对象"), @ApiField("查询到多个是否抛出异常，可以传入指定提示语，如果提示语为空，则不提示，总的提示与格式：根据%s查询到多条数据，只需要传递%s部分即可")}, returns=@ApiField("首个对象"))
	public SystemApiInterfacesDataDo findFirst(SystemApiInterfacesSearchDo search, String multipleException){
		List<SystemApiInterfacesDataDo> list=this.findList(search);
		if(ObjectUtils.isEmpty(list)){
			return null;
		}
		if(ObjectUtils.isNotEmpty(multipleException)){
			ExceptionUtils.trueException(list.size()>1, "multiple.data.found", multipleException);
		}
		return list.get(0);
	}
	
	@ApiMethod(value="将Api注解转换为接口文档对象", params = {@ApiField("api注解"), @ApiField("api注解的类")}, returns = @ApiField("接口文档目录对象"))
	public List<SystemApiInterfacesInsertBatchItemDo> handleApiAnno(Api apiAnno, Class<?> apiClass) {
		List<SystemApiInterfacesInsertBatchItemDo> insertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesInsertBatchItemDo insert;
		RequestMapping mapping=apiClass.getAnnotation(RequestMapping.class);
		String[] paths;
		if(ObjectUtils.isNotEmpty(mapping)) {
			paths = mapping.value();
			if(ObjectUtils.isEmpty(paths)) {
				paths = new String[]{""};
			}
		}else {
			paths = new String[]{""};
		}
		String[] pathCommentMap=null;
		String[] comments = apiAnno.value();
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", apiClass.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = apiAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", apiClass.getName(), paths.length, comments.length);
		}
		String signature=EncryptionUtils.md5Hex(FileUtils.reader(new InputStreamReader(Thread.currentThread().getContextClassLoader().getResourceAsStream(apiClass.getName().replace(".", "/")+".class")), true));
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setPath(paths[i]);
			search.setMustParentId(true);
			existsInterfaces = this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("catalog");
				insert.setName(pathCommentMap[i]);
				insert.setPath(paths[i]);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(apiClass.getAnnotation(Deprecated.class)));
				insert.setClassSignature(signature);
				insert.setIsChange(true);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				if(signature.equals(existsInterfaces.getClassSignature())) {
					insert.setIsChange(false);
				}else {
					insert.setIsChange(true);
					SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
	    			update.setId(existsInterfaces.getId());
	    			update.setType("catalog");
	    			update.setName(pathCommentMap[i]);
	    			update.setPath(paths[i]);
	    			update.setDescribe(pathDescribeMap[i]);
	    			update.setOpenLevel(9);
	    			update.setDeprecated(ObjectUtils.isNotEmpty(apiClass.getAnnotation(Deprecated.class)));
	    			update.setClassSignature(signature);
	    			this.update(update, false);
				}
			}
			insertList.add(insert);
		}
		return insertList;
	}
	
	@ApiMethod(value="将反射方法转换为接口对象", params = {@ApiField("反射方法"), @ApiField("父目录")}, returns = @ApiField("接口列表对象"))
	public List<SystemApiInterfacesInsertBatchItemDo> handleMethodAnno(Method[] methods, List<SystemApiInterfacesInsertBatchItemDo> folderList){
		List<SystemApiInterfacesInsertBatchItemDo> insertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		int sort, matchSort;
		for (SystemApiInterfacesInsertBatchItemDo folder : folderList) {
			sort=1;
			for (Method method : methods) {
				matchSort=sort;
				sort = handleRequestMapping(insertList, method, sort, folder);
				if(matchSort!=sort) {//表示命中
					continue;
				}
				matchSort=sort;
				sort = handleGetMapping(insertList, method, sort, folder);
				if(matchSort!=sort) {//表示命中
					continue;
				}
				matchSort=sort;
				sort = handlePostMapping(insertList, method, sort, folder);
				if(matchSort!=sort) {//表示命中
					continue;
				}
				matchSort=sort;
				sort = handlePutMapping(insertList, method, sort, folder);
				if(matchSort!=sort) {//表示命中
					continue;
				}
				matchSort=sort;
				sort = handleDeleteMapping(insertList, method, sort, folder);
			}
		}
		return insertList;
	}
	
	@ApiMethod(value="处理spring的RequestMapping注解", params = {@ApiField("汇总的接口对象"), @ApiField("RequestMapping对应的java反射方法"), @ApiField("接口顺序"), @ApiField("的接口父目录")}, returns = @ApiField("接口最终顺序"))
	private int handleRequestMapping(List<SystemApiInterfacesInsertBatchItemDo> insertList, Method method, int sort, SystemApiInterfacesInsertBatchItemDo folder) {
		ApiMethod methodAnno=method.getAnnotation(ApiMethod.class);
		RequestMapping requestMapping=method.getAnnotation(RequestMapping.class);
		if(ObjectUtils.isEmpty(requestMapping)) {
			return sort;
		}
		String[] paths=ObjectUtils.init(requestMapping.value(), requestMapping.path());
		String[] comments = methodAnno.value();
		String[] pathCommentMap=null;
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = methodAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		RequestMethod[] requestMethods = requestMapping.method();
		if(ObjectUtils.isEmpty(requestMethods)) {
			requestMethods=new RequestMethod[paths.length];
			for (int i = 0, length = paths.length; i < length; i++) {
				requestMethods[i]=RequestMethod.GET;
			}
		}else if(requestMethods.length==1) {
			if(paths.length>1) {
				RequestMethod allTheSame=requestMethods[0];
				requestMethods=new RequestMethod[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					requestMethods[i]=allTheSame;
				}
			}
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, requestMethods.length);
		}
		SystemApiInterfacesInsertBatchItemDo insert;
		List<SystemApiInterfacesInsertBatchItemDo> subInsertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			String path = folder.getPath()+paths[i];
			String methodName = requestMethods[i].name();
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setParentId(folder.getId());
			search.setPath(path);
			search.setMethod(methodName);
			existsInterfaces=this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("interface");
				insert.setName(pathCommentMap[i]);
				insert.setMethod(methodName);
				insert.setPath(path);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
				insert.setSort(sort);
				insert.setParentId(folder.getId());
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
    			update.setId(existsInterfaces.getId());
    			update.setName(pathCommentMap[i]);
    			update.setPath(path);
    			update.setDescribe(pathDescribeMap[i]);
    			update.setOpenLevel(9);
    			update.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
    			this.update(update, false);
			}
			subInsertList.add(insert);
			sort++;
		}
		insertList.addAll(subInsertList);
		return sort;
	}
	
	@ApiMethod(value="处理spring的GetMapping注解", params = {@ApiField("汇总的接口对象"), @ApiField("RequestMapping对应的java反射方法"), @ApiField("接口顺序"), @ApiField("的接口父目录")}, returns = @ApiField("接口最终顺序"))
	private int handleGetMapping(List<SystemApiInterfacesInsertBatchItemDo> insertList, Method method, int sort, SystemApiInterfacesInsertBatchItemDo folder) {
		ApiMethod methodAnno=method.getAnnotation(ApiMethod.class);
		GetMapping requestMapping=method.getAnnotation(GetMapping.class);
		if(ObjectUtils.isEmpty(requestMapping)) {
			return sort;
		}
		String[] paths=ObjectUtils.init(requestMapping.value(), requestMapping.path());
		String[] comments = methodAnno.value();
		String[] pathCommentMap=null;
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = methodAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		RequestMethod[] requestMethods=new RequestMethod[paths.length];
		for (int i = 0, length = paths.length; i < length; i++) {
			requestMethods[i]=RequestMethod.GET;
		}
		SystemApiInterfacesInsertBatchItemDo insert;
		List<SystemApiInterfacesInsertBatchItemDo> subInsertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			String path = folder.getPath()+paths[i];
			String methodName = requestMethods[i].name();
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setParentId(folder.getId());
			search.setPath(path);
			search.setMethod(methodName);
			existsInterfaces=this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("interface");
				insert.setName(pathCommentMap[i]);
				insert.setMethod(methodName);
				insert.setPath(path);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
				insert.setSort(sort);
				insert.setParentId(folder.getId());
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
    			update.setId(existsInterfaces.getId());
    			update.setName(pathCommentMap[i]);
    			update.setPath(path);
    			update.setDescribe(pathDescribeMap[i]);
    			update.setOpenLevel(9);
    			update.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
    			this.update(update, false);
			}
			subInsertList.add(insert);
			sort++;
		}
		insertList.addAll(subInsertList);
		return sort;
	}
	
	@ApiMethod(value="处理spring的PostMapping注解", params = {@ApiField("汇总的接口对象"), @ApiField("RequestMapping对应的java反射方法"), @ApiField("接口顺序"), @ApiField("的接口父目录")}, returns = @ApiField("接口最终顺序"))
	private int handlePostMapping(List<SystemApiInterfacesInsertBatchItemDo> insertList, Method method, int sort, SystemApiInterfacesInsertBatchItemDo folder) {
		ApiMethod methodAnno=method.getAnnotation(ApiMethod.class);
		PostMapping requestMapping=method.getAnnotation(PostMapping.class);
		if(ObjectUtils.isEmpty(requestMapping)) {
			return sort;
		}
		String[] paths=ObjectUtils.init(requestMapping.value(), requestMapping.path());
		String[] comments = methodAnno.value();
		String[] pathCommentMap=null;
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = methodAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		RequestMethod[] requestMethods=new RequestMethod[paths.length];
		for (int i = 0, length = paths.length; i < length; i++) {
			requestMethods[i]=RequestMethod.POST;
		}
		SystemApiInterfacesInsertBatchItemDo insert;
		List<SystemApiInterfacesInsertBatchItemDo> subInsertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			String path = folder.getPath()+paths[i];
			String methodName = requestMethods[i].name();
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setParentId(folder.getId());
			search.setPath(path);
			search.setMethod(methodName);
			existsInterfaces=this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("interface");
				insert.setName(pathCommentMap[i]);
				insert.setMethod(methodName);
				insert.setPath(path);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
				insert.setSort(sort);
				insert.setParentId(folder.getId());
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
    			update.setId(existsInterfaces.getId());
    			update.setName(pathCommentMap[i]);
    			update.setPath(path);
    			update.setDescribe(pathDescribeMap[i]);
    			update.setOpenLevel(9);
    			update.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
    			this.update(update, false);
			}
			subInsertList.add(insert);
			sort++;
		}
		insertList.addAll(subInsertList);
		return sort;
	}
	
	@ApiMethod(value="处理spring的PutMapping注解", params = {@ApiField("汇总的接口对象"), @ApiField("RequestMapping对应的java反射方法"), @ApiField("接口顺序"), @ApiField("的接口父目录")}, returns = @ApiField("接口最终顺序"))
	private int handlePutMapping(List<SystemApiInterfacesInsertBatchItemDo> insertList, Method method, int sort, SystemApiInterfacesInsertBatchItemDo folder) {
		ApiMethod methodAnno=method.getAnnotation(ApiMethod.class);
		PutMapping requestMapping=method.getAnnotation(PutMapping.class);
		if(ObjectUtils.isEmpty(requestMapping)) {
			return sort;
		}
		String[] paths=ObjectUtils.init(requestMapping.value(), requestMapping.path());
		String[] comments = methodAnno.value();
		String[] pathCommentMap=null;
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = methodAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		RequestMethod[] requestMethods=new RequestMethod[paths.length];
		for (int i = 0, length = paths.length; i < length; i++) {
			requestMethods[i]=RequestMethod.PUT;
		}
		SystemApiInterfacesInsertBatchItemDo insert;
		List<SystemApiInterfacesInsertBatchItemDo> subInsertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			String path = folder.getPath()+paths[i];
			String methodName = requestMethods[i].name();
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setParentId(folder.getId());
			search.setPath(path);
			search.setMethod(methodName);
			existsInterfaces=this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("interface");
				insert.setName(pathCommentMap[i]);
				insert.setMethod(methodName);
				insert.setPath(path);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
				insert.setSort(sort);
				insert.setParentId(folder.getId());
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
    			update.setId(existsInterfaces.getId());
    			update.setName(pathCommentMap[i]);
    			update.setPath(path);
    			update.setDescribe(pathDescribeMap[i]);
    			update.setOpenLevel(9);
    			update.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
    			this.update(update, false);
			}
			subInsertList.add(insert);
			sort++;
		}
		insertList.addAll(subInsertList);
		return sort;
	}
	
	@ApiMethod(value="处理spring的DeleteMapping注解", params = {@ApiField("汇总的接口对象"), @ApiField("RequestMapping对应的java反射方法"), @ApiField("接口顺序"), @ApiField("的接口父目录")}, returns = @ApiField("接口最终顺序"))
	private int handleDeleteMapping(List<SystemApiInterfacesInsertBatchItemDo> insertList, Method method, int sort, SystemApiInterfacesInsertBatchItemDo folder) {
		ApiMethod methodAnno=method.getAnnotation(ApiMethod.class);
		DeleteMapping requestMapping=method.getAnnotation(DeleteMapping.class);
		if(ObjectUtils.isEmpty(requestMapping)) {
			return sort;
		}
		String[] paths=ObjectUtils.init(requestMapping.value(), requestMapping.path());
		String[] comments = methodAnno.value();
		String[] pathCommentMap=null;
		if(comments.length==1) {
			if(paths.length>1) {
				pathCommentMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathCommentMap[i]=comments[0]+(i+1);
				}
			}else {
				pathCommentMap=comments;
			}
		}else if(comments.length==paths.length) {
			pathCommentMap=comments;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		String[] pathDescribeMap=null;
		String[] describes = methodAnno.describe();
		if(describes.length==1) {
			if(paths.length>1) {
				pathDescribeMap=new String[paths.length];
				for (int i = 0, length=paths.length; i < length; i++) {
					pathDescribeMap[i]=describes[0]+(i+1);
				}
			}else {
				pathDescribeMap=describes;
			}
		}else if(describes.length==paths.length) {
			pathDescribeMap=describes;
		}else {
			throw ExceptionUtils.message("abnormal.interface.annotation.relationship", method.getDeclaringClass()+"."+method.getName(), paths.length, comments.length);
		}
		RequestMethod[] requestMethods=new RequestMethod[paths.length];
		for (int i = 0, length = paths.length; i < length; i++) {
			requestMethods[i]=RequestMethod.DELETE;
		}
		SystemApiInterfacesInsertBatchItemDo insert;
		List<SystemApiInterfacesInsertBatchItemDo> subInsertList=new ArrayList<SystemApiInterfacesInsertBatchItemDo>();
		SystemApiInterfacesSearchDo search;
		SystemApiInterfacesDataDo existsInterfaces;
		for (int i = 0, length = paths.length; i < length; i++) {
			String path = folder.getPath()+paths[i];
			String methodName = requestMethods[i].name();
			search=new SystemApiInterfacesSearchDo();
			search.setServer(serverName);
			search.setParentId(folder.getId());
			search.setPath(path);
			search.setMethod(methodName);
			existsInterfaces=this.findFirst(search, "接口API");
			if(ObjectUtils.isEmpty(existsInterfaces)) {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				insert.setServer(serverName);
				insert.setType("interface");
				insert.setName(pathCommentMap[i]);
				insert.setMethod(methodName);
				insert.setPath(path);
				insert.setDescribe(pathDescribeMap[i]);
				insert.setOpenLevel(9);
				insert.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
				insert.setSort(sort);
				insert.setParentId(folder.getId());
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				this.save(insert, false);
			}else {
				insert=new SystemApiInterfacesInsertBatchItemDo();
				this.convertPojo(existsInterfaces, insert);
				insert.setMethodAnno(methodAnno);
				insert.setMethodClass(method);
				SystemApiInterfacesUpdateDo update=new SystemApiInterfacesUpdateDo();
    			update.setId(existsInterfaces.getId());
    			update.setName(pathCommentMap[i]);
    			update.setPath(path);
    			update.setDescribe(pathDescribeMap[i]);
    			update.setOpenLevel(9);
    			update.setDeprecated(ObjectUtils.isNotEmpty(method.getAnnotation(Deprecated.class)));
    			this.update(update, false);
			}
			subInsertList.add(insert);
			sort++;
		}
		insertList.addAll(subInsertList);
		return sort;
	}
	
	@ApiMethod(value="设置测试请求信息", params = {@ApiField("请求接口数据"), @ApiField("body参数列表")})
	public void setTestInfo(SystemApiInterfacesViewVo view, List<SystemApiParamTreeVo> bodyParamList) {
		String path=view.getPath();
		StringBuilder testPath=new StringBuilder();
		int first = 0, index = path.indexOf("{");
		List<SystemApiParamViewVo> pathParamList;
		while(index!=-1) {
			testPath.append(path, first, index);
			first=index+1;
			index=path.indexOf("}", first);
			if(index==-1) {
				break;
			}
			String param=path.substring(first, index);
			if(ObjectUtils.isNotEmpty(view.getPathParamList())) {
				pathParamList=view.getPathParamList().stream().filter(p -> p.getParamKey().equals(param)).collect(Collectors.toList());
				if(ObjectUtils.isNotEmpty(pathParamList) && ObjectUtils.isNotEmpty(pathParamList.get(0).getTestExample())) {
					testPath.append(pathParamList.get(0).getTestExample());
				}
			}
			first=index+1;
			index = path.indexOf("{", first);
		}
		if(first<path.length()) {
			testPath.append(path.substring(first));
		}
		if(ObjectUtils.isNotEmpty(view.getUrlParamList())) {
			index=0;
			for (SystemApiParamViewVo urlParam : view.getUrlParamList()) {
				testPath.append(index==0?"?":"&").append(urlParam.getParamKey()).append("=").append(ObjectUtils.init(urlParam.getTestExample(), ""));
				index++;
			}
		}
		view.setTestPath(testPath.toString());
		view.setHeaders("{"+FileUtils.nextLine()+"\t\""+tokenName+"\":\"\""+FileUtils.nextLine()+"}");
		if(ObjectUtils.isNotEmpty(bodyParamList)) {
			StringBuilder body=new StringBuilder();
			ExceptionUtils.trueException(bodyParamList.size()!=1, "only.one.object.can.exist.in.the.request.body");
			for (SystemApiParamTreeVo bodyParam : bodyParamList) {
				if(ApiParamTypeEnum.ARRAY.getValue().equals(bodyParam.getParamType())) {
					body.append("[").append(FileUtils.nextLine()).append("{").append(FileUtils.nextLine());
				}else if(ApiParamTypeEnum.OBJECT.getValue().equals(bodyParam.getParamType())) {
					body.append("{").append(FileUtils.nextLine());
				}else {
					ExceptionUtils.message("the.body.request.method.must.be.an.array.or.object");
				}
				parseBodyChild(body, bodyParam.getChildren(), 1);
				if(ApiParamTypeEnum.ARRAY.getValue().equals(bodyParam.getParamType())) {
					body.append("}").append(FileUtils.nextLine()).append("]");
				}else if(ApiParamTypeEnum.OBJECT.getValue().equals(bodyParam.getParamType())) {
					body.append("}");
				}
			}
			view.setTestBodyParamJson(body.toString());
		}
	}
	
	@ApiMethod(value="解析body孩子节点", params = {@ApiField("body字符串缓存"), @ApiField("body孩子列表")})
	private void parseBodyChild(StringBuilder body, List<SystemApiParamTreeVo> childrenList, int depth) {
		if(ObjectUtils.isNotEmpty(childrenList)) {
			int index=0, length=childrenList.size();
			for (SystemApiParamTreeVo bodyParam : childrenList) {
				for (int i = 0; i < depth; i++) {
					body.append("\t");
				}
				
				body.append("\"").append(bodyParam.getParamKey()).append("\"").append(":");
				if(ApiParamTypeEnum.ARRAY.getValue().equals(bodyParam.getParamType())) {
					body.append("[").append(FileUtils.nextLine()).append("{").append(FileUtils.nextLine());
				}else if(ApiParamTypeEnum.OBJECT.getValue().equals(bodyParam.getParamType())) {
					body.append("{").append(FileUtils.nextLine());
				}else if(ApiParamTypeEnum.STRING.getValue().equals(bodyParam.getParamType()) || ApiParamTypeEnum.CHAR.getValue().equals(bodyParam.getParamType()) || ApiParamTypeEnum.DATETIME.getValue().equals(bodyParam.getParamType())){
					body.append("\"").append(bodyParam.getTestExample()).append("\"");
				}else {
					body.append(bodyParam.getTestExample());
				}
				if(ApiParamTypeEnum.ARRAY.getKey().equals(bodyParam.getParamType()) || ApiParamTypeEnum.OBJECT.getKey().equals(bodyParam.getParamKey())) {
					parseBodyChild(body, bodyParam.getChildren(), depth+1);
				}
				if(ApiParamTypeEnum.ARRAY.getKey().equals(bodyParam.getParamType())) {
					body.append("}").append(FileUtils.nextLine()).append("]");
				}else if(ApiParamTypeEnum.OBJECT.getKey().equals(bodyParam.getParamKey())) {
					body.append("}");
				}
				if(index<length-1) {
					body.append(",").append(FileUtils.nextLine());
				}else {
					body.append(FileUtils.nextLine());
				}
				index++;
			}
		}
	}
}
